package com.dragon.sdgp.common.security;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.dragon.sdgp.common.R;
import com.dragon.sdgp.config.SecurityConfig;
import com.dragon.sdgp.entity.SysUser;
import com.dragon.sdgp.service.SysUserService;
import com.dragon.sdgp.util.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * @AUTHOR : Dragon_Yang
 * @File : JwtAuthenticationFilter
 * @DESCRIPTION : JWT验证过滤器
 * @DATE : 2023/2/27 21:10
 */
@Slf4j
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    @Autowired
    MyUserDetailsServiceImpl myUserDetailsService;

    @Autowired
    private SysUserService sysUserService;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String token = request.getHeader("authorization");
        log.info("请求的URL ==> {}",request.getRequestURI());
        //如果token为空或url在白名单里则放行
        if(Arrays.asList(SecurityConfig.URL_WHITELIST).contains(request.getRequestURI())){
            chain.doFilter(request, response);
            return;
        }
        if(StrUtil.isEmpty(token)){
            response.getOutputStream().write(JSONUtil.toJsonStr(R.fail(400, "Authorization not allow null, please login again")).getBytes("GBK"));
            return;
        }
        DecodedJWT decodedJWT = null;
        try {
            decodedJWT = JWTUtil.verifyToken(token);
            if (decodedJWT == null) {
                log.error("token valid error!");
                throw new JWTDecodeException("token valid error!");
            }
        }catch (Exception e){
            log.info(e.getMessage());
            OutputStream outputStream = response.getOutputStream();
            outputStream.write(JSONUtil.toJsonStr(R.fail(400, "请先登录！")).getBytes());
            outputStream.flush();
            outputStream.close();
            return;
        }

        String account = decodedJWT.getClaim("account").asString();
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(account, null, new ArrayList<>());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        chain.doFilter(request, response);
    }
}
